package service

import (
	"context"
	"crypto/md5"
	"encoding/hex"
	"errors"
	"fmt"
	"jgame-api/app"
	"jgame-api/keys"
	"jgame-api/util"
	"math/rand"
	"strconv"
	"time"
)

func CheckToken(token string) (int64, error) {
	if len(token) < 64 {
		return 0, errors.New("token too short")
	}

	uidEncode := string([]byte(token)[:32])
	unq := string([]byte(token)[32:])

	uid, err := util.NewToken(app.Conf.Security.UserTokenHashSalt, app.Conf.Security.UserTokenHashAlphabet).Decode(uidEncode)

	if err != nil {
		return 0, errors.New("internal service error")
	}

	cacheKey := keys.GetUserTokenKey(strconv.FormatInt(uid, 10))
	tokenStr := app.RDB.Client.Get(context.TODO(), cacheKey)

	if tokenStr.Val() != unq {
		return 0, fmt.Errorf("invalid token")
	}

	return uid, nil
}

func GetUserToken(uid int) string {
	uidStr, err := util.NewToken(app.Conf.Security.UserTokenHashSalt, app.Conf.Security.UserTokenHashAlphabet).Encode(uid)
	if err != nil {
		app.Logger.Errorf("internal service error")
		return ""
	}

	//唯一字符串
	uniqueString := GetUniqueStr()

	cacheKey := keys.GetUserTokenKey(strconv.FormatInt(int64(uid), 10))
	err = app.RDB.Client.Set(context.TODO(), cacheKey, uniqueString, 86400).Err()

	if err != nil {
		app.Logger.Errorf("set token error")
		return ""
	}

	return uidStr + uniqueString
}

func GetUniqueStr() string {
	// 初始化随机数种子
	rand.Seed(time.Now().UnixNano())

	// 获取当前时间和随机数
	microTime := time.Now().UnixNano()
	randomNumber := rand.Intn(99999999)

	// 拼接字符串并计算 MD5
	data := fmt.Sprintf("%d%d", microTime, randomNumber)
	hash := md5.Sum([]byte(data))

	// 转换为 16 进制字符串
	uniqueString := hex.EncodeToString(hash[:])

	return uniqueString
}
